package com.lan.evaluator;

import com.lan.ScriptContext;
import com.lan.antlr.ScriptBaseVisitor;
import com.lan.antlr.ScriptParser;
import com.lan.model.Symbol;
import com.lan.model.V;
import com.lan.model.Value;
import com.lan.model.symbol.*;
import com.lan.parse.SymbolTree;
import com.lan.script.*;
import com.lan.util.Utils;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
 * 在AST上解释执行脚本
 */
public class AstEvaluator extends ScriptBaseVisitor<Object> {

    private ScriptContext context;

    private SymbolTree symbolTree;

    protected boolean traceStackFrame = false;

    protected boolean traceFunctionCall = false;

    ///////////////////////////////////////////////////////////
    /// 栈桢的管理
    private Stack<StackFrame> stack = new Stack<>();


    public AstEvaluator(ScriptContext context) {
        this.context = context;
        this.symbolTree = context.getSymbolTree();
    }

    private void popStack() {
        stack.pop();
    }

    private void dumpStackFrame() {
        System.out.println("\nStack Frames ----------------");
        for (StackFrame frame : stack) {
            System.out.println(frame);
        }
        System.out.println("-----------------------------\n");
    }


    /**
     * 栈桢入栈。
     * 其中最重要的任务，是要保证栈桢的parent设置正确。否则，
     * (1)随着栈的变深，查找变量的性能会降低；
     * (2)甚至有可能找错栈桢，比如在递归(直接或间接)的场景下。
     *
     * @param frame
     */
    private void pushStack(StackFrame frame) {
        if (stack.size() > 0) {
            //从栈顶到栈底依次查找
            for (int i = stack.size() - 1; i > 0; i--) {
                StackFrame f = stack.get(i);

                if (f.getScope().getScope() == frame.getScope().getScope()) {
                    /*
                        如果新加入的栈桢，跟某个已有的栈桢的scope是一样的，那么这俩的parentFrame也一样。
                        因为它们原本就是同一级的嘛。
                        比如：
                        void foo(){};
                        void bar(foo());

                        或者：
                        void foo();
                        if (...){
                            foo();
                        }
                    */
                    frame.setParent(f.getParent());
                    break;
                } else if (f.getScope() == frame.getScope().getScope()) {
                      /*
                        如果新加入的栈桢，是某个已有的栈桢的下一级，那么就把把这个父子关系建立起来。比如：
                        void foo(){
                            if (...){  //把这个块往栈桢里加的时候，就符合这个条件。
                            }
                        }
                        再比如,下面的例子:
                        class MyClass{
                            void foo();
                        }
                        MyClass c = MyClass();  //先加Class的栈桢，里面有类的属性，包括父类的
                        c.foo();                //再加foo()的栈桢
                     */
                    frame.setParent(f);
                    break;
                } else if (frame.getObject() instanceof FunctionObject) {
                     /*
                        这是针对函数可能是一等公民的情况。这个时候，函数运行时的作用域，与声明时的作用域会不一致。
                        我在这里设计了一个“receiver”的机制，意思是这个函数是被哪个变量接收了。要按照这个receiver的作用域来判断。
                         */
                    FunctionObject functionObject = (FunctionObject) frame.getObject();
                    if (functionObject.getFunction() != null && functionObject.getFunction().getScope() == f.getScope()) {
                        frame.setParent(f);
                        break;
                    }
                }
            }

            if (frame.getParent() == null) {
                frame.setParent(stack.peek());
            }
        }
        stack.push(frame);
        if (traceStackFrame) {
            dumpStackFrame();
        }
    }

    public Value getValue(Variable variable) {
        StackFrame f = stack.peek();
        ScriptObject o = null;
        while (f != null) {
            if (f.getScope().containsSymbol(variable)) {
                //对于对象来说，会查找所有父类的属性
                o = f.getObject();
                break;
            }
            f = f.getParent();
        }

        //通过正常的作用域找不到，就从闭包里找
        //原理：ScriptObject中可能有一些变量，其作用域跟StackFrame.scope是不同的。
        if (o == null) {
            f = stack.peek();
            while (f != null) {
                if (f.contains(variable)) {
                    o = f.getObject();
                    break;
                }
                f = f.getParent();
            }
        }
        return new V(variable, o);
    }


    @Override
    public Object visitProg(ScriptParser.ProgContext ctx) {
        Object rtn = null;
        pushStack(new StackFrame(symbolTree.getBlock()));
        rtn = visitBlockStatements(ctx.blockStatements());
        popStack();
        return rtn;
    }


    @Override
    public Object visitBlockStatements(ScriptParser.BlockStatementsContext ctx) {
        Object rtn = null;
        for (ScriptParser.BlockStatementContext child : ctx.blockStatement()) {
            rtn = visitBlockStatement(child);
            if (rtn instanceof BreakObject) {
                //如果返回的是break，那么不执行下面的语句
                break;
            } else if (rtn instanceof ReturnObject) {
                //碰到Return, 退出函数
                // TODO 要能层层退出一个个block，弹出一个栈桢
                break;
            }
        }
        return rtn;
    }

    @Override
    public Object visitStatement(ScriptParser.StatementContext ctx) {
        Object rtn = null;
        if (ctx.block() != null) {
            rtn = visitBlock(ctx.block());
        } else if (ctx.IF() != null) {
            Boolean condition = (Boolean) visitParExpression(ctx.parExpression());
            if (Boolean.TRUE == condition) {
                rtn = visitBlock(ctx.block());
            } else if (ctx.ELSE() != null) {
                rtn = visitStatement(ctx.statement());
            }
        } else if (ctx.FOR() != null) {
            // 添加StackFrame
            Block scope = (Block) context.nodeOfScope(ctx);
            StackFrame frame = new StackFrame(scope);
            pushStack(frame);
            ScriptParser.ForControlContext forControl = ctx.forControl();
            // 初始化部分执行一次
            if (forControl.forInit() != null) {
                rtn = visitForInit(forControl.forInit());
            }

            while (true) {
                Boolean condition = true; // 如果没有条件判断部分，意味着一直循环
                if (forControl.expression() != null) {
                    Object value = visitExpression(forControl.expression());
                    if (value instanceof Value) {
                        condition = (Boolean) ((Value) value).getValue();
                    } else {
                        condition = (Boolean) value;
                    }
                }

                if (condition) {
                    // 执行for的语句体
                    rtn = visitBlock(ctx.block());

                    //处理break
                    if (rtn instanceof BreakObject) {
                        rtn = null;
                        break;
                    } else if (rtn instanceof ReturnObject) {
                        //return
                        break;
                    } else if (rtn instanceof ContinueObject) {
                        continue;
                    }
                    // 执行forUpdate，通常是“i++”这样的语句。这个执行顺序不能出错。
                    if (forControl.forUpdate != null) {
                        visitExpressionList(forControl.forUpdate);
                    }
                } else {
                    break;
                }
            }
            // 去掉StackFrame
            popStack();
        } else if (ctx.WHILE() != null) {
            //while循环
            if (ctx.parExpression().expression() != null && ctx.block() != null) {
                while (true) {
                    //每次循环都要计算一下循环条件
                    Boolean condition = true;
                    Object value = visitExpression(ctx.parExpression().expression());
                    if (value instanceof Value) {
                        condition = (Boolean) ((Value) value).getValue();
                    } else {
                        condition = (Boolean) value;
                    }

                    if (condition) {
                        //执行while后面的语句
                        if (condition) {
                            rtn = visitBlock(ctx.block());
                            //break
                            if (rtn instanceof BreakObject) {
                                rtn = null;  //清除BreakObject，也就是只跳出一层循环
                                break;
                            }
                            //return
                            else if (rtn instanceof ReturnObject) {
                                break;
                            }
                        }
                    } else {
                        break;
                    }
                }
            }
        } else if (ctx.BREAK() != null) {
            //break语句
            rtn = BreakObject.instance();
        } else if (ctx.CONTINUE() != null) {
            rtn = ContinueObject.instance();
        } else if (ctx.RETURN() != null) {
            //return语句
            if (ctx.expression() != null) {
                rtn = visitExpression(ctx.expression());
                //return语句应该不需要左值
                if (rtn instanceof Value) {
                    rtn = ((Value) rtn).getValue();
                }

            }
        } else if (ctx.statementExpression != null) {
            rtn = visitExpression(ctx.statementExpression);
        }
        return rtn;
    }

    @Override
    public Object visitForInit(ScriptParser.ForInitContext ctx) {
        Object rtn = null;
        if (ctx.variableDeclarators() != null) {
            rtn = visitVariableDeclarators(ctx.variableDeclarators());
        } else if (ctx.expressionList() != null) {
            rtn = visitExpressionList(ctx.expressionList());
        }
        return rtn;
    }

    @Override
    public Object visitExpressionList(ScriptParser.ExpressionListContext ctx) {
        Object rtn = null;
        for (ScriptParser.ExpressionContext child : ctx.expression()) {
            rtn = visitExpression(child);
        }
        return rtn;
    }

    @Override
    public Object visitParExpression(ScriptParser.ParExpressionContext ctx) {
        return visitExpression(ctx.expression());
    }

    @Override
    public Object visitBlockStatement(ScriptParser.BlockStatementContext ctx) {
        Object rtn = null;
        if (ctx.variableDeclarators() != null) {
            rtn = visitVariableDeclarators(ctx.variableDeclarators());
        } else if (ctx.statement() != null) {
            rtn = visitStatement(ctx.statement());
        }
        return rtn;
    }

    @Override
    public Object visitVariableDeclarators(ScriptParser.VariableDeclaratorsContext ctx) {
        Object rtn = null;
        // Integer typeType = (Integer)visitTypeType(ctx.typeType()); //后面要利用这个类型信息
        for (ScriptParser.VariableDeclaratorContext child : ctx.variableDeclarator()) {
            rtn = visitVariableDeclarator(child);
        }
        return rtn;
    }

    @Override
    public Object visitVariableDeclarator(ScriptParser.VariableDeclaratorContext ctx) {
        Object rtn = null;
        Value value = (Value) visitVariableDeclaratorId(ctx.variableDeclaratorId());
        if (ctx.variableInitializer() != null) {
            rtn = visitVariableInitializer(ctx.variableInitializer());
            if (rtn instanceof Value) {
                rtn = ((Value) rtn).getValue();
            }
            value.setValue(rtn);
        }
        return rtn;
    }


    @Override
    public Object visitVariableDeclaratorId(ScriptParser.VariableDeclaratorIdContext ctx) {
        Object rtn = null;
        Symbol symbol = context.symbolOfNode(ctx);
        rtn = getValue((Variable) symbol);
        return rtn;
    }

    @Override
    public Object visitVariableInitializer(ScriptParser.VariableInitializerContext ctx) {
        Object rtn = null;
        if (ctx.expression() != null) {
            rtn = visitExpression(ctx.expression());
        }
        return rtn;
    }


    @Override
    public Object visitExpression(ScriptParser.ExpressionContext ctx) {
        Object rtn = null;
        if (ctx.primary() != null) {
            rtn = visitPrimary(ctx.primary());
        } else if (ctx.expression() != null && ctx.bop != null && ctx.expression().size() >= 2) {
            if (ctx.expression().size() == 2) {
                Object left = visitExpression(ctx.expression(0));
                Object right = visitExpression(ctx.expression(1));
                Object leftObject = left;
                Object rightObject = right;

                if (left instanceof Value) {
                    leftObject = ((Value) left).getValue();
                }

                if (right instanceof Value) {
                    rightObject = ((Value) right).getValue();
                }

                switch (ctx.bop.getType()) {
                    case ScriptParser.ADD:
                        rtn = Utils.add(leftObject, rightObject);
                        break;
                    case ScriptParser.SUB:
                        rtn = Utils.sub(leftObject, rightObject);
                        break;
                    case ScriptParser.MUL:
                        rtn = Utils.mul(leftObject, rightObject);
                        break;
                    case ScriptParser.DIV:
                        rtn = Utils.div(leftObject, rightObject);
                        break;
                    case ScriptParser.EQUAL:
                        rtn = Utils.EQ(leftObject, rightObject);
                        break;
                    case ScriptParser.NOTEQUAL:
                        rtn = Utils.NotEq(leftObject, rightObject);
                        break;
                    case ScriptParser.LE:
                        rtn = Utils.LE(leftObject, rightObject);
                        break;
                    case ScriptParser.LT:
                        rtn = Utils.LT(leftObject, rightObject);
                        break;
                    case ScriptParser.GT:
                        rtn = Utils.GT(leftObject, rightObject);
                        break;
                    case ScriptParser.AND:
                        rtn = (Boolean) leftObject && (Boolean) rightObject;
                        break;
                    case ScriptParser.OR:
                        rtn = (Boolean) leftObject || (Boolean) rightObject;
                        break;
                    case ScriptParser.ASSIGN:
                        if (left instanceof Value) {
                            ((Value) left).setValue(rightObject);
                            rtn = right;
                        } else {
                            System.out.println("Unsupported feature during assignment");
                        }
                        break;
                    default:
                        break;
                }
            }
        } else if (ctx.bop != null && ctx.bop.getType() == ScriptParser.DOT) {
            // 此语法是左递归的，算法体现这一点
            Object leftObject = visitExpression(ctx.expression(0));
            if (leftObject instanceof Value) {
                Object value = ((Value) leftObject).getValue();
                if (value instanceof ClazzObject) {
                    ClazzObject object = (ClazzObject) value;
//                    Variable leftVar = (Variable) context.symbolOfNode(ctx.expression(0));
                    // 获得field或调用方法
                    if (ctx.name() != null) {
                        Variable variable = (Variable) context.symbolOfNode(ctx);
                        variable = context.lookupVariable(object.getType(), variable.getName());
                        Value v = new V(variable, object);
                        rtn = v;
                    } else if (ctx.functionCall() != null) {
                        //要先计算方法的参数，才能加对象的StackFrame.
                        if (traceFunctionCall) {
                            System.out.println("\n>>MethodCall : " + ctx.getText());
                        }
                        rtn = methodCall(object, ctx.functionCall());
                    }
                }
            } else {
                System.out.println("Expecting an Object Reference");
            }
        } else if (ctx.postfix != null) {
            //后缀运算，例如 i++ 或i--
            Object value = visitExpression(ctx.expression(0));
            Value v = null;
            if (value instanceof Value) {
                v = (Value) value;
                value = v.getValue();
            }

            switch (ctx.postfix.getType()) {
                case ScriptParser.INC:
                    rtn = Utils.INC(value);
                    v.setValue(rtn);
                    break;
                case ScriptParser.DEC:
                    rtn = Utils.DEC(value);
                    v.setValue(rtn);
                    break;
                default:
                    break;
            }
        } else if (ctx.functionCall() != null) {
            rtn = visitFunctionCall(ctx.functionCall());
        }
        return rtn;
    }

    @Override
    public Object visitFunctionCall(ScriptParser.FunctionCallContext ctx) {
        Object rtn = null;
        //这是调用时的名称
        String functionName = ctx.name().getText();
        //如果调用的是类的缺省构造函数，则直接创建对象并返回
        Symbol symbol = context.symbolOfNode(ctx);
        if (symbol instanceof DefaultConstructor) {
            //类的缺省构造函数。没有一个具体函数跟它关联，只是指向了一个类。
            //return createAndInitClassObject((Class) symbol);  //返回新创建的对象
            return createAndInitClassObject(((DefaultConstructor) symbol).Class());  //返回新创建的对象
        }

        //在上下文中查找出函数，并根据需要创建FunctionObject
        FunctionObject functionObject = getFunctionObject(ctx);
        Function function = functionObject.getFunction();

        //如果是对象的构造方法，则按照对象方法调用去执行，并返回所创建出的对象。
        if (function.isConstructor()) {
            Clazz theClazz = (Clazz) function.getScope();
            ClazzObject newObject = createAndInitClassObject(theClazz);  //先做缺省的初始化
            methodCall(newObject, ctx);
            return newObject;  //返回新创建的对象。
        }

        //计算参数值
        List<Object> paramValues = calcParamValues(ctx);

        rtn = functionCall(functionObject, paramValues);
        return rtn;
    }

    ////////////////////////对象初始化///////////////////////////////////

    /**
     * 从父类到子类层层执行缺省的初始化方法，即不带参数的初始化方法。
     */
    protected ClazzObject createAndInitClassObject(Clazz theClazz) {
        ClazzObject obj = new ClazzObject();
        obj.setClazz(theClazz);
        Stack<Clazz> ancestorChain = new Stack<>();
        // 从上到下执行缺省的初始化方法
        ancestorChain.push(theClazz);
        // 执行缺省的初始化方法
        StackFrame frame = new StackFrame(obj);
        pushStack(frame);
        while (ancestorChain.size() > 0) {
            Clazz c = ancestorChain.pop();
            defaultObjectInit(c, obj);
        }
        popStack();
        return obj;
    }

    /**
     * 类的缺省初始化方法
     *
     * @param theClazz
     * @param obj
     */
    private void defaultObjectInit(Clazz theClazz, ClazzObject obj) {
        for (Symbol symbol : theClazz.getSymbols()) {
            // 把变量加到obj里，缺省先都初始化成null，不允许有未初始化的
            if (symbol instanceof Variable) {
                obj.withMeta((Variable) symbol, null);
            }
        }
        // 执行缺省初始化
        // 执行缺省初始化
        ScriptParser.ClassBodyContext ctx = ((ScriptParser.ClassDeclarationContext) theClazz.getCtx()).classBody();
        visitClassBody(ctx);
    }

    @Override
    public Object visitClassBody(ScriptParser.ClassBodyContext ctx) {
        Object rtn = null;
        for (ScriptParser.ClassBodyDeclarationContext child : ctx.classBodyDeclaration()) {
            rtn = visitClassBodyDeclaration(child);
        }
        return rtn;
    }

    @Override
    public Object visitClassBodyDeclaration(ScriptParser.ClassBodyDeclarationContext ctx) {
        Object rtn = null;
        if (ctx.fieldDeclaration() != null) {
            rtn = visitFieldDeclaration(ctx.fieldDeclaration());
        }
        return rtn;
    }

    @Override
    public Object visitFieldDeclaration(ScriptParser.FieldDeclarationContext ctx) {
        Object rtn = null;
        if (ctx.variableDeclarators() != null) {
            rtn = visitVariableDeclarators(ctx.variableDeclarators());
        }
        return rtn;
    }

    @Override
    public Object visitFunctionDeclaration(ScriptParser.FunctionDeclarationContext ctx) {
        return visitFunctionBody(ctx.functionBody());
    }

    @Override
    public Object visitFunctionBody(ScriptParser.FunctionBodyContext ctx) {
        Object rtn = null;
        if (ctx.block() != null) {
            rtn = visitBlock(ctx.block());
        }
        return rtn;
    }

    /**
     * 对象方法调用
     * 要先计算完参数的值，然后再添加对的StackFrame,然后再调用方法
     *
     * @param classObject  世纪调用时的对象。通过这个对象可以获得真实的类
     * @param functionCall
     * @return
     */
    private Object methodCall(ClazzObject classObject, ScriptParser.FunctionCallContext functionCall) {
        Object rtn = null;
        //查找函数，并根据需要创建FunctionObject
        //如果查找到的是类的属性,FunctionType 型，需要把再对象的栈帧里查
        StackFrame classFrame = new StackFrame(classObject);
        pushStack(classFrame);
        FunctionObject functionObject = getFunctionObject(functionCall);
        popStack();

        //对普通的类方法，需要在运行时动态绑定
        Function function = functionObject.getFunction();
        //对普通的类方法，需要在运行时动态绑定
        Clazz theClazz = classObject.getType();   //这是从对象获得的类型，是真实类型。可能是变量声明时的类型的子类
        if (!function.isConstructor()) {
            //从当前类逐级向上查找，找到正确的方法定义
            Function overrided = theClazz.getFunction(function.getName(), function.getParamTypes());
            //原来这个function，可能指向一个父类的实现。现在从子类中可能找到重载后的方法，这个时候要绑定到子类的方法上
            if (overrided != null && overrided != function) {
                function = overrided;
                functionObject.setFunction(function);
            }
        }


        //计算参数值
        List<Object> paramValues = calcParamValues(functionCall);
        //对象的frame要等到函数参数都计算完了才能添加。
        //StackFrame classFrame = new StackFrame(classObject);
        pushStack(classFrame);

        //执行函数
        rtn = functionCall(functionObject, paramValues);

        //弹出栈桢
        popStack();

        return rtn;
    }

    /**
     * 计算某个函数调用时的参数值
     *
     * @param ctx
     * @return
     */
    private List<Object> calcParamValues(ScriptParser.FunctionCallContext ctx) {
        List<Object> paramValues = new LinkedList<>();
        if (ctx.expressionList() != null) {
            for (ScriptParser.ExpressionContext exp : ctx.expressionList().expression()) {
                Object value = visitExpression(exp);
                if (value instanceof Value) {
                    value = ((Value) value).getValue();
                }
                paramValues.add(value);
            }
        }
        return paramValues;
    }

    /**
     * 执行一个函数的方法体。需要先设置参数值，然后再执行代码。
     *
     * @param functionObject
     * @param paramValues
     * @return
     */
    private Object functionCall(FunctionObject functionObject, List<Object> paramValues) {
        Object rtn = null;
        //添加函数的栈桢
        StackFrame functionFrame = new StackFrame(functionObject);
        pushStack(functionFrame);
        // 给参数赋值，这些值进入functionFrame
        ScriptParser.FunctionDeclarationContext functionCode = (ScriptParser.FunctionDeclarationContext) functionObject.getFunction().getCtx();
        if (functionCode.formalParameters().formalParameterList() != null) {
            for (int i = 0; i < functionCode.formalParameters().formalParameterList().variableDeclaratorId().size(); i++) {
                ScriptParser.VariableDeclaratorIdContext param = functionCode.formalParameters().formalParameterList().variableDeclaratorId(i);
                Value value = (Value) visitVariableDeclaratorId(param);
                value.setValue(paramValues.get(i));
            }
        }
        // 调用函数（方法）体
        rtn = visitFunctionDeclaration(functionCode);
        // 弹出StackFrame
        popStack(); //函数的栈桢

        //如果由一个return语句返回，真实返回值会被封装在一个ReturnObject里。
        if (rtn instanceof ReturnObject) {
            rtn = ((ReturnObject) rtn).getReturnValue();
        }

        return rtn;
    }


    /**
     * 根据函数调用的上下文，返回一个FunctionObject。
     * 对于函数类型的变量，这个functionObject是存在变量里的；
     * 对于普通的函数调用，此时创建一个。
     *
     * @param ctx
     * @return
     */
    private FunctionObject getFunctionObject(ScriptParser.FunctionCallContext ctx) {
        if (ctx.name() == null) return null;  //暂时不支持this和super
        Function function = null;
        FunctionObject functionObject = null;
        Symbol symbol = context.symbolOfNode(ctx);
        //函数类型的变量
        if (symbol instanceof Variable) {
            Variable variable = (Variable) symbol;
            Value v = getValue(variable);
            Object value = v.getValue();
            if (value instanceof FunctionObject) {
                functionObject = (FunctionObject) value;
                function = functionObject.getFunction();
            }
        } else if (symbol instanceof Function) {
            //普通函数
            function = (Function) symbol;
        } else {
            //报错
            String functionName = ctx.name().getText();  //这是调用时的名称，不一定是真正的函数名，还可能是函数类型的变量名
            context.log("unable to find function or function variable " + functionName, ctx);
            return null;
        }
        if (functionObject == null) {
            functionObject = new FunctionObject(function);
        }
        return functionObject;
    }


    @Override
    public Object visitPrimary(ScriptParser.PrimaryContext ctx) {
        Object rtn = null;
        if (ctx.literal() != null) {
            //字面量
            rtn = visitLiteral(ctx.literal());
        } else if (ctx.name() != null) {
            //变量
            Symbol symbol = context.symbolOfNode(ctx);
            if (symbol instanceof Variable) {
                rtn = getValue((Variable) symbol);
            } else if (symbol instanceof Function) {
                FunctionObject obj = new FunctionObject((Function) symbol);
                rtn = obj;
            }
        } else if (ctx.expression() != null) {
            rtn = visitExpression(ctx.expression());
        }
        return rtn;
    }

    @Override
    public Object visitLiteral(ScriptParser.LiteralContext ctx) {
        Object rtn = null;
        if (ctx.DECIMAL_LITERAL() != null) {
            //整数
            rtn = Integer.valueOf(ctx.DECIMAL_LITERAL().getText());
        } else if (ctx.FLOAT_LITERAL() != null) {
            //浮点数
            rtn = Double.valueOf(ctx.FLOAT_LITERAL().getText());
        } else if (ctx.BOOL_LITERAL() != null) {
            //布尔值
            if (ctx.BOOL_LITERAL().getText().equals("true")) {
                rtn = Boolean.TRUE;
            } else {
                rtn = Boolean.FALSE;
            }
        } else if (ctx.STRING_LITERAL() != null) {
            //字符串
            String withQuotationMark = ctx.STRING_LITERAL().getText();
            rtn = withQuotationMark.substring(1, withQuotationMark.length() - 1);
        }

        //null字面量
        else if (ctx.NULL_LITERAL() != null) {
            rtn = NullObject.instance();
        }
        return rtn;
    }
}
